/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.isfd.domain.vo.DataChangeDetailVo;
import com.comac.ins.isfd.domain.vo.DataChangeResultVo;
import com.comac.ins.isfd.domain.vo.IsfdDatabaseModelConfigFieldVo;
import com.comac.ins.isfd.domain.vo.IsfdDatabaseModelConfigTableVo;
import com.comac.ins.isfd.service.IIsfdDatabaseDataManagementProService;
import com.comac.ins.isfd.service.IIsfdDatabaseModelConfigService;
import com.comac.ins.isfd.service.IIsfdDatabaseMongoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据库建模配置Service业务层处理
 *
 * @author Lion Li
 * @date 2024-11-27
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class IsfdDatabaseDataManagementProServiceImpl implements IIsfdDatabaseDataManagementProService {

    @Autowired
    private IIsfdDatabaseModelConfigService configService;

    @Autowired
    private IIsfdDatabaseMongoService mongoService;


    // 新增方法
    @Override
    public Map<String, Object> exportDataAsJson(Long modelId) {
        // 1. 获取模型配置
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(modelId);
        Map<String, IsfdDatabaseModelConfigTableVo> modelNameTableMap = fieldTableList.stream()
            .collect(Collectors.toMap(
                IsfdDatabaseModelConfigTableVo::getModelName,
                table -> table
            ));

        // 2. 获取当前模型配置
        IsfdDatabaseModelConfigTableVo currentModel = fieldTableList.stream()
            .filter(table -> table.getId().equals(modelId))
            .findFirst()
            .orElseThrow(() -> new BaseException("模型配置不存在: " + modelId));

        // 3. 查询当前模型数据
        List<Document> documents = mongoService.findAll(currentModel.getTableName());
        List<Map<String, Object>> modelData = documents.stream()
            .map(doc -> {
                Map<String, Object> map = new HashMap<>();
                doc.forEach((key, value) -> {
                    // 转换ObjectId为字符串
                    if (value instanceof ObjectId) {
                        map.put(key, ((ObjectId) value).toHexString());
                    } else {
                        map.put(key, value);
                    }
                });
                return map;
            }).collect(Collectors.toList());

        // 4. 递归构建数据结构
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("data", buildJsonStructure(currentModel, modelData, modelNameTableMap));
        return result;
    }

    // 修改后的递归构建方法
    private Object buildJsonStructure(IsfdDatabaseModelConfigTableVo model,
                                      List<Map<String, Object>> dataList,
                                      Map<String, IsfdDatabaseModelConfigTableVo> modelNameTableMap) {
        if (dataList.isEmpty()) return Collections.emptyMap();

        List<Map<String, Object>> resultList = new ArrayList<>();

        for (Map<String, Object> data : dataList) {
            Map<String, Object> node = new LinkedHashMap<>();

            // 处理普通字段
            for (IsfdDatabaseModelConfigFieldVo field : model.getFieldVoList()) {
                if (!"模型".equals(field.getFieldType())) {
                    Object value = data.get(field.getFieldName());
                    if (value != null) {
                        node.put(field.getFieldName(), value);
                    }
                }
            }

            // 递归处理嵌套模型
            for (IsfdDatabaseModelConfigFieldVo field : model.getFieldVoList()) {
                if ("模型".equals(field.getFieldType())) {
                    IsfdDatabaseModelConfigTableVo childModel = modelNameTableMap.get(field.getFieldName());
                    if (childModel != null && data.containsKey(field.getFieldName())) {
                        Object childData = data.get(field.getFieldName());

                        if (childData instanceof List) {
                            // 处理数组类型的子模型
                            List<String> childIds = (List<String>) childData;
                            List<Document> rawChildren = mongoService.findByIds(
                                childModel.getTableName(),
                                childIds
                            );

                            List<Map<String, Object>> children = rawChildren.stream().map(doc -> {
                                Map<String, Object> map = new HashMap<>();
                                doc.forEach((k, v) -> {
                                    if (v instanceof ObjectId) {
                                        map.put(k, ((ObjectId) v).toHexString());
                                    } else {
                                        map.put(k, v);
                                    }
                                });
                                return map;
                            }).toList();


                            node.put(field.getFieldName(),
                                buildJsonStructure(childModel, children, modelNameTableMap));
                        }
//                        else{
//                            // 处理数组类型的子模型
//                            List<String> childIds = Collections.singletonList(childData).stream()
//                                .map(Object::toString)
//                                .collect(Collectors.toList());;
//                            List<Map<String, Object>> children = mongoService.findByIds(
//                                childModel.getTableName(),
//                                childIds
//                            );
//                            children = children.stream().map(doc -> {
//                                Map<String, Object> map = new HashMap<>();
//                                doc.forEach((k, v) -> {
//                                    if (v instanceof ObjectId) {
//                                        map.put(k, ((ObjectId) v).toHexString());
//                                    } else {
//                                        map.put(k, v);
//                                    }
//                                });
//                                return map;
//                            }).collect(Collectors.toList());
//
//
//                            node.put(field.getFieldName(),
//                                buildJsonStructure(childModel, children, modelNameTableMap));
//                        }
                    }
                }
            }
            resultList.add(node);
        }
        if(model.getModelName().equals("data")){
            return resultList.size() == 1 ? resultList.get(0) : resultList;
        }

//        return resultList.size() == 1 ? resultList.get(0) : resultList;
        return resultList;
    }

    @Override
    public DataChangeResultVo checkDataChanges(Long modelId, String startTime, String endTime) {
        List<IsfdDatabaseModelConfigTableVo> tables = configService.getFieldTableList(modelId);
        List<DataChangeDetailVo> details = new ArrayList<>();

        for (IsfdDatabaseModelConfigTableVo table : tables) {

            // 查询新增记录
            List<Document> createList = mongoService.findByTimeRangeAndDeleteFlag(table.getTableName(), startTime, endTime, null,   null, 0, "created", null);

            // 查询更新记录（排除新增的）
            List<Document> updateList = mongoService.findByTimeRangeAndDeleteFlag(table.getTableName(), null, null, startTime,   endTime, 0, "updated", null);

            // 查询删除记录
            List<Document> deleteList = mongoService.findByTimeRangeAndDeleteFlag(table.getTableName(), null, null, startTime,   endTime, 1, "deleted", null);

            details.add(buildDetail(table.getTableName(), table.getModelName(), createList, updateList, deleteList));
        }

        // 排序
        Map<String, Integer> tableDepthMap = tables.stream()
            .collect(Collectors.toMap(IsfdDatabaseModelConfigTableVo::getTableName, IsfdDatabaseModelConfigTableVo::getDepth));

        details.sort((a, b) -> {
            int depthA = tableDepthMap.getOrDefault(a.getTableName(), 0);
            int depthB = tableDepthMap.getOrDefault(b.getTableName(), 0);
            return Integer.compare(depthB, depthA); // 按 depth 降序
        });

        boolean hasChange = !details.isEmpty();

        return new DataChangeResultVo(
            hasChange,
            details
        );
    }
    private DataChangeDetailVo buildDetail(String tableName, String modelName, List<Document> created, List<Document> updated, List<Document> deleted) {
        DataChangeDetailVo detail = new DataChangeDetailVo();
        detail.setModelName(modelName);
        detail.setTableName(tableName);

        if (!CollectionUtils.isEmpty(created)) {
            List<Map<String, Object>> sortedCreated = created.stream()
                .map(this::sortFieldsByKeywordPriority)
                .toList();
            detail.setCreated(sortedCreated);
        }

        if (!CollectionUtils.isEmpty(updated)) {
            List<Map<String, Object>> sortedUpdated = updated.stream()
                .map(this::sortFieldsByKeywordPriority)
                .toList();
            detail.setUpdated(sortedUpdated);
        }

        if (!CollectionUtils.isEmpty(deleted)) {
            List<Map<String, Object>> sortedDeleted = deleted.stream()
                .map(this::sortFieldsByKeywordPriority)
                .toList();
            detail.setDeleted(sortedDeleted);
        }


        return detail;
    }

    public Map<String, Object> sortFieldsByKeywordPriority(Map<String, Object> original) {
        List<String> idKeywords = List.of("id");
        List<String> nameTypeKeywords = List.of("name", "type");

        Map<String, Object> result = new LinkedHashMap<>();

        // Step 1: 放 id 相关字段
        original.entrySet().stream()
            .filter(entry -> idKeywords.stream().anyMatch(k -> entry.getKey().toLowerCase().contains(k)))
            .forEach(entry -> result.put(entry.getKey(), entry.getValue()));

        // Step 2: 放 name/type 相关字段（不包含已加的 id 字段）
        original.entrySet().stream()
            .filter(entry -> !result.containsKey(entry.getKey()))
            .filter(entry -> nameTypeKeywords.stream().anyMatch(k -> entry.getKey().toLowerCase().contains(k)))
            .forEach(entry -> result.put(entry.getKey(), entry.getValue()));

        // Step 3: 其余字段
        original.entrySet().stream()
            .filter(entry -> !result.containsKey(entry.getKey()))
            .forEach(entry -> result.put(entry.getKey(), entry.getValue()));

        return result;
    }


}
